package cn.jingyuan.bee.utils.lang;

import cn.jingyuan.bee.utils.NumberUtils;
import cn.jingyuan.bee.utils.ObjectUtils;
import cn.jingyuan.bee.utils.RegExUtils;
import cn.jingyuan.bee.utils.StringUtils;
import cn.jingyuan.bee.utils.date.DateUtils;
import cn.jingyuan.bee.utils.exceptions.ValidateException;

import java.net.MalformedURLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字段验证器
 */
public class Validator {

    /** 英文字母 、数字和下划线 */
    public static final Pattern GENERAL = PatternPool.GENERAL;

    /** 数字 */
    public static final Pattern NUMBERS = PatternPool.NUMBERS;

    /** 分组 */
    public static final Pattern GROUP_VAR = PatternPool.GROUP_VAR;

    /** IP v4 */
    public static final Pattern IPV4 = PatternPool.IPV4;

    /** IP v6 */
    public static final Pattern IPV6 = PatternPool.IPV6;

    /** 货币 */
    public static final Pattern MONEY = PatternPool.MONEY;

    /** 邮件 */
    public static final Pattern EMAIL = PatternPool.EMAIL;

    /** 移动电话 */
    public static final Pattern MOBILE = PatternPool.MOBILE;

    /** 身份证号码 */
    public static final Pattern CITIZEN_ID = PatternPool.CITIZEN_ID;

    /** 邮编 */
    public static final Pattern ZIP_CODE = PatternPool.ZIP_CODE;

    /** 生日 */
    public static final Pattern BIRTHDAY = PatternPool.BIRTHDAY;

    /** URL */
    public static final Pattern URL = PatternPool.URL;

    /** Http URL */
    public static final Pattern URL_HTTP = PatternPool.URL_HTTP;

    /** 中文字、英文字母、数字和下划线 */
    public static final Pattern GENERAL_WITH_CHINESE = PatternPool.GENERAL_WITH_CHINESE;

    /** UUID */
    public static final Pattern UUID = PatternPool.UUID;

    /** 不带横线的 UUID */
    public static final Pattern UUID_SIMPLE = PatternPool.UUID_SIMPLE;

    /** 中国车牌号码 */
    public static final Pattern PLATE_NUMBER = PatternPool.PLATE_NUMBER;

    private Validator() { }

    /**
     * 给定值是否为<code>true</code>
     *
     * @param value 值
     *
     * @return 是否为<code>true</code>
     */
    public static boolean isTrue(boolean value) {
        return value;
    }

    /**
     * 给定值是否不为<code>false</code>
     *
     * @param value 值
     *
     * @return 是否不为<code>false</code>
     */
    public static boolean isFalse(boolean value) {
        return !value;
    }

    /**
     * 检查指定值是否为<code>true</code>
     *
     * @param value 值
     * @param errorMsgTemplate 错误消息内容模板（变量使用 {} 表示）
     * @param params 模板中变量替换后的值
     *
     * @return 检查过后的值
     *
     * @throws ValidateException 检查不满足条件抛出的异常
     */
    public static boolean validateTrue(boolean value, String errorMsgTemplate, Object... params) throws ValidateException {
        if (isFalse(value)) {
            throw new ValidateException(errorMsgTemplate, params);
        }
        return value;
    }

    /**
     * 检查指定值是否为<code>false</code>
     *
     * @param value 值
     * @param errorMsgTemplate 错误消息内容模板（变量使用 {} 表示）
     * @param params 模板中变量替换后的值
     *
     * @return 检查过后的值
     *
     * @throws ValidateException 检查不满足条件抛出的异常
     */
    public static boolean validateFalse(boolean value, String errorMsgTemplate, Object... params) throws ValidateException {
        if (isTrue(value)) {
            throw new ValidateException(errorMsgTemplate, params);
        }
        return value;
    }

    /**
     * 给定值是否为<code>null</code>
     *
     * @param value 值
     *
     * @return 是否为<code>null</code>
     */
    public static boolean isNull(Object value) {
        return null == value;
    }

    /**
     * 给定值是否不为<code>null</code>
     *
     * @param value 值
     *
     * @return 是否不为<code>null</code>
     */
    public static boolean isNotNull(Object value) {
        return null != value;
    }

    /**
     * 检查指定值是否为<code>null</code>
     *
     * @param <T> 被检查的对象类型
     * @param value 值
     * @param errorMsgTemplate 错误消息内容模板（变量使用 {} 表示）
     * @param params 模板中变量替换后的值
     *
     * @return 检查过后的值
     *
     * @throws ValidateException 检查不满足条件抛出的异常
     */
    public static <T> T validateNull(T value, String errorMsgTemplate, Object... params) throws ValidateException {
        if (isNotNull(value)) {
            throw new ValidateException(errorMsgTemplate, params);
        }
        return value;
    }

    /**
     * 检查指定值是否非<code>null</code>
     *
     * @param <T> 被检查的对象类型
     * @param value 值
     * @param errorMsgTemplate 错误消息内容模板（变量使用 {} 表示）
     * @param params 模板中变量替换后的值
     *
     * @return 检查过后的值
     *
     * @throws ValidateException 检查不满足条件抛出的异常
     */
    public static <T> T validateNotNull(T value, String errorMsgTemplate, Object... params) throws ValidateException {
        if (isNull(value)) {
            throw new ValidateException(errorMsgTemplate, params);
        }
        return value;
    }

    /**
     * 验证是否为空<br>
     * 对于 String 类型判定是否为 empty(null 或 "")<br>
     *
     * @param value 值
     *
     * @return 是否为空
     */
    public static boolean isEmpty(Object value) {
        return (null == value || (value instanceof String && StringUtils.isEmpty((String) value)));
    }

    /**
     * 验证是否为非空<br>
     * 对于 String 类型判定是否为 empty(null 或 "")<br>
     *
     * @param value 值
     *
     * @return 是否为空
     */
    public static boolean isNotEmpty(Object value) {
        return !isEmpty(value);
    }

    /**
     * 验证是否为空，非空时抛出异常<br>
     * 对于 String 类型判定是否为 empty(null 或 "")<br>
     *
     * @param <T> 值类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值，验证通过返回此值，空值
     *
     * @throws ValidateException 验证异常
     */
    public static <T> T validateEmpty(T value, String errorMsg) throws ValidateException {
        if (isNotEmpty(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为非空，为空时抛出异常<br>
     * 对于 String 类型判定是否为 empty(null 或 "")<br>
     *
     * @param <T> 值类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值，验证通过返回此值，非空值
     *
     * @throws ValidateException 验证异常
     */
    public static <T> T validateNotEmpty(T value, String errorMsg) throws ValidateException {
        if (isEmpty(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否相等<br>
     * 当两值都为 null 返回 true
     *
     * @param t1 对象 1
     * @param t2 对象 2
     *
     * @return 当两值都为 null 或相等返回 true
     */
    public static boolean equal(Object t1, Object t2) {
        return ObjectUtils.equal(t1, t2);
    }

    /**
     * 验证是否相等，不相等抛出异常<br>
     *
     * @param t1 对象 1
     * @param t2 对象 2
     * @param errorMsg 错误信息
     *
     * @return 相同值
     *
     * @throws ValidateException 验证异常
     */
    public static Object validateEqual(Object t1, Object t2, String errorMsg) throws ValidateException {
        if (!equal(t1, t2)) {
            throw new ValidateException(errorMsg);
        }
        return t1;
    }

    /**
     * 验证是否不等，相等抛出异常<br>
     *
     * @param t1 对象 1
     * @param t2 对象 2
     * @param errorMsg 错误信息
     *
     * @throws ValidateException 验证异常
     */
    public static void validateNotEqual(Object t1, Object t2, String errorMsg) throws ValidateException {
        if (equal(t1, t2)) {
            throw new ValidateException(errorMsg);
        }
    }

    /**
     * 验证是否非空且与指定值相等<br>
     * 当数据为空时抛出验证异常<br>
     * 当两值不等时抛出异常
     *
     * @param t1 对象 1
     * @param t2 对象 2
     * @param errorMsg 错误信息
     *
     * @throws ValidateException 验证异常
     */
    public static void validateNotEmptyAndEqual(Object t1, Object t2, String errorMsg) throws ValidateException {
        validateNotEmpty(t1, errorMsg);
        validateEqual(t1, t2, errorMsg);
    }

    /**
     * 验证是否非空且与指定值相等<br>
     * 当数据为空时抛出验证异常<br>
     * 当两值相等时抛出异常
     *
     * @param t1 对象 1
     * @param t2 对象 2
     * @param errorMsg 错误信息
     *
     * @throws ValidateException 验证异常
     */
    public static void validateNotEmptyAndNotEqual(Object t1, Object t2, String errorMsg) throws ValidateException {
        validateNotEmpty(t1, errorMsg);
        validateNotEqual(t1, t2, errorMsg);
    }

    /**
     * 通过正则表达式验证
     *
     * @param regex 正则
     * @param value 值
     *
     * @return 是否匹配正则
     */
    public static boolean isMactchRegex(String regex, CharSequence value) {
        return RegExUtils.isMatch(regex, value);
    }

    /**
     * 通过正则表达式验证<br>
     * 不符合正则抛出 {@link ValidateException} 异常
     *
     * @param <T> 字符串类型
     * @param regex 正则
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateMatchRegex(String regex, T value, String errorMsg) throws ValidateException {
        if (!isMactchRegex(regex, value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 通过正则表达式验证
     *
     * @param pattern 正则模式
     * @param value 值
     *
     * @return 是否匹配正则
     */
    public static boolean isMactchRegex(Pattern pattern, CharSequence value) {
        return RegExUtils.isMatch(pattern, value);
    }

    /**
     * 验证是否为英文字母 、数字和下划线
     *
     * @param value 值
     *
     * @return 是否为英文字母 、数字和下划线
     */
    public static boolean isGeneral(CharSequence value) {
        return isMactchRegex(GENERAL, value);
    }

    /**
     * 验证是否为英文字母 、数字和下划线
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateGeneral(T value, String errorMsg) throws ValidateException {
        if (!isGeneral(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为给定长度范围的英文字母 、数字和下划线
     *
     * @param value 值
     * @param min 最小长度，负数自动识别为 0
     * @param max 最大长度，0 或负数表示不限制最大长度
     *
     * @return 是否为给定长度范围的英文字母 、数字和下划线
     */
    public static boolean isGeneral(CharSequence value, int min, int max) {
        if (min < 0) {
            min = 0;
        }
        String reg = "^\\w{" + min + "," + max + "}$";
        if (max <= 0) {
            reg = "^\\w{" + min + ",}$";
        }
        return isMactchRegex(reg, value);
    }

    /**
     * 验证是否为给定长度范围的英文字母 、数字和下划线
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param min 最小长度，负数自动识别为 0
     * @param max 最大长度，0 或负数表示不限制最大长度
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateGeneral(T value, int min, int max, String errorMsg) throws ValidateException {
        if (!isGeneral(value, min, max)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为给定最小长度的英文字母 、数字和下划线
     *
     * @param value 值
     * @param min 最小长度，负数自动识别为 0
     *
     * @return 是否为给定最小长度的英文字母 、数字和下划线
     */
    public static boolean isGeneral(CharSequence value, int min) {
        return isGeneral(value, min, 0);
    }

    /**
     * 验证是否为给定最小长度的英文字母 、数字和下划线
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param min 最小长度，负数自动识别为 0
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateGeneral(T value, int min, String errorMsg) throws ValidateException {
        return validateGeneral(value, min, 0, errorMsg);
    }

    /**
     * 判断字符串是否全部为字母组成，包括大写和小写字母和汉字
     *
     * @param value 值
     *
     * @return 是否全部为字母组成，包括大写和小写字母和汉字
     */
    public static boolean isLetter(CharSequence value) {
        return StringUtils.isAllCharMatch(value, new cn.jingyuan.bee.utils.lang.Matcher<Character>() {

            @Override
            public boolean match(Character t) {
                return Character.isLetter(t);
            }
        });
    }

    /**
     * 验证是否全部为字母组成，包括大写和小写字母和汉字
     *
     * @param <T> 字符串类型
     * @param value 表单值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateLetter(T value, String errorMsg) throws ValidateException {
        if (!isLetter(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 判断字符串是否全部为大写字母
     *
     * @param value 值
     *
     * @return 是否全部为大写字母
     */
    public static boolean isUpperCase(CharSequence value) {
        return StringUtils.isAllCharMatch(value, new cn.jingyuan.bee.utils.lang.Matcher<Character>() {

            @Override
            public boolean match(Character t) {
                return Character.isUpperCase(t);
            }
        });
    }

    /**
     * 验证字符串是否全部为大写字母
     *
     * @param <T> 字符串类型
     * @param value 表单值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateUpperCase(T value, String errorMsg) throws ValidateException {
        if (!isUpperCase(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 判断字符串是否全部为小写字母
     *
     * @param value 值
     *
     * @return 是否全部为小写字母
     */
    public static boolean isLowerCase(CharSequence value) {
        return StringUtils.isAllCharMatch(value, new cn.jingyuan.bee.utils.lang.Matcher<Character>() {

            @Override
            public boolean match(Character t) {
                return Character.isLowerCase(t);
            }
        });
    }

    /**
     * 验证字符串是否全部为小写字母
     *
     * @param <T> 字符串类型
     * @param value 表单值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateLowerCase(T value, String errorMsg) throws ValidateException {
        if (!isLowerCase(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证该字符串是否是数字
     *
     * @param value 字符串内容
     *
     * @return 是否是数字
     */
    public static boolean isNumber(CharSequence value) {
        return NumberUtils.isNumber(value);
    }

    /**
     * 验证是否为数字
     *
     * @param value 表单值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static String validateNumber(String value, String errorMsg) throws ValidateException {
        if (!isNumber(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证该字符串是否是字母（包括大写和小写字母）
     *
     * @param value 字符串内容
     *
     * @return 是否是字母（包括大写和小写字母）
     */
    public static boolean isWord(CharSequence value) {
        return isMactchRegex(PatternPool.WORD, value);
    }

    /**
     * 验证是否为字母（包括大写和小写字母）
     *
     * @param <T> 字符串类型
     * @param value 表单值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateWord(T value, String errorMsg) throws ValidateException {
        if (!isWord(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为货币
     *
     * @param value 值
     *
     * @return 是否为货币
     */
    public static boolean isMoney(CharSequence value) {
        return isMactchRegex(MONEY, value);
    }

    /**
     * 验证是否为货币
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateMoney(T value, String errorMsg) throws ValidateException {
        if (!isMoney(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;

    }

    /**
     * 验证是否为邮政编码（中国）
     *
     * @param value 值
     *
     * @return 是否为邮政编码（中国）
     */
    public static boolean isZipCode(CharSequence value) {
        return isMactchRegex(ZIP_CODE, value);
    }

    /**
     * 验证是否为邮政编码（中国）
     *
     * @param <T> 字符串类型
     * @param value 表单值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateZipCode(T value, String errorMsg) throws ValidateException {
        if (!isZipCode(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为可用邮箱地址
     *
     * @param value 值
     *
     * @return 否为可用邮箱地址
     */
    public static boolean isEmail(CharSequence value) {
        return isMactchRegex(EMAIL, value);
    }

    /**
     * 验证是否为可用邮箱地址
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateEmail(T value, String errorMsg) throws ValidateException {
        if (!isEmail(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为手机号码（中国）
     *
     * @param value 值
     *
     * @return 是否为手机号码（中国）
     */
    public static boolean isMobile(CharSequence value) {
        return isMactchRegex(MOBILE, value);
    }

    /**
     * 验证是否为手机号码（中国）
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateMobile(T value, String errorMsg) throws ValidateException {
        if (!isMobile(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为身份证号码（18 位中国）<br>
     * 出生日期只支持到到 2999 年
     *
     * @param value 值
     *
     * @return 是否为身份证号码（18 位中国）
     */
    public static boolean isCitizenId(CharSequence value) {
        return isMactchRegex(CITIZEN_ID, value);
    }

    /**
     * 验证是否为身份证号码（18 位中国）<br>
     * 出生日期只支持到到 2999 年
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateCitizenIdNumber(T value, String errorMsg) throws ValidateException {
        if (!isCitizenId(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为生日
     *
     * @param year 年，从 1900 年开始计算
     * @param month 月，从 1 开始计数
     * @param day 日，从 1 开始计数
     *
     * @return 是否为生日
     */
    public static boolean isBirthday(int year, int month, int day) {
        // 验证年
        int thisYear = DateUtils.thisYear();
        if (year < 1900 || year > thisYear) {
            return false;
        }

        // 验证月
        if (month < 1 || month > 12) {
            return false;
        }

        // 验证日
        if (day < 1 || day > 31) {
            return false;
        }
        // 检查几个特殊月的最大天数
        if (day == 31 && (month == 4 || month == 6 || month == 9 || month == 11)) {
            return false;
        }
        if (month == 2) {
            // 在 2 月，非闰年最大 28，闰年最大 29
            return day < 29 || (day == 29 && DateUtils.isLeapYear(year));
        }
        return true;
    }

    /**
     * 验证是否为生日<br>
     * 只支持以下几种格式：
     * <ul>
     * <li>yyyyMMdd</li>
     * <li>yyyy-MM-dd</li>
     * <li>yyyy/MM/dd</li>
     * <li>yyyy.MM.dd</li>
     * <li>yyyy 年 MM 月 dd 日</li>
     * </ul>
     *
     * @param value 值
     *
     * @return 是否为生日
     */
    public static boolean isBirthday(CharSequence value) {
        if (isMactchRegex(BIRTHDAY, value)) {
            Matcher matcher = BIRTHDAY.matcher(value);
            if (matcher.find()) {
                int year = Integer.parseInt(matcher.group(1));
                int month = Integer.parseInt(matcher.group(3));
                int day = Integer.parseInt(matcher.group(5));
                return isBirthday(year, month, day);
            }
        }
        return false;
    }

    /**
     * 验证验证是否为生日
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateBirthday(T value, String errorMsg) throws ValidateException {
        if (!isBirthday(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为 IPV4 地址
     *
     * @param value 值
     *
     * @return 是否为 IPV4 地址
     */
    public static boolean isIpv4(CharSequence value) {
        return isMactchRegex(IPV4, value);
    }

    /**
     * 验证是否为 IPV4 地址
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateIpv4(T value, String errorMsg) throws ValidateException {
        if (!isIpv4(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为 IPV6 地址
     *
     * @param value 值
     *
     * @return 是否为 IPV6 地址
     */
    public static boolean isIpv6(CharSequence value) {
        return isMactchRegex(IPV6, value);
    }

    /**
     * 验证是否为 IPV6 地址
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateIpv6(T value, String errorMsg) throws ValidateException {
        if (!isIpv6(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为 MAC 地址
     *
     * @param value 值
     *
     * @return 是否为 MAC 地址
     */
    public static boolean isMac(CharSequence value) {
        return isMactchRegex(PatternPool.MAC_ADDRESS, value);
    }

    /**
     * 验证是否为 MAC 地址
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateMac(T value, String errorMsg) throws ValidateException {
        if (!isMac(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为中国车牌号
     *
     * @param value 值
     *
     * @return 是否为中国车牌号
     */
    public static boolean isPlateNumber(CharSequence value) {
        return isMactchRegex(PLATE_NUMBER, value);
    }

    /**
     * 验证是否为中国车牌号
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validatePlateNumber(T value, String errorMsg) throws ValidateException {
        if (!isPlateNumber(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为 URL
     *
     * @param value 值
     *
     * @return 是否为 URL
     */
    public static boolean isUrl(CharSequence value) {
        try {
            new java.net.URL(StringUtils.string(value));
        } catch (MalformedURLException e) {
            return false;
        }
        return true;
    }

    /**
     * 验证是否为 URL
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateUrl(T value, String errorMsg) throws ValidateException {
        if (!isUrl(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为汉字
     *
     * @param value 值
     *
     * @return 是否为汉字
     */
    public static boolean isChinese(CharSequence value) {
        return isMactchRegex("^" + RegExUtils.RE_CHINESE + "+$", value);
    }

    /**
     * 验证是否为汉字
     *
     * @param <T> 字符串类型
     * @param value 表单值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateChinese(T value, String errorMsg) throws ValidateException {
        if (!isChinese(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为中文字、英文字母、数字和下划线
     *
     * @param value 值
     *
     * @return 是否为中文字、英文字母、数字和下划线
     */
    public static boolean isGeneralWithChinese(CharSequence value) {
        return isMactchRegex(GENERAL_WITH_CHINESE, value);
    }

    /**
     * 验证是否为中文字、英文字母、数字和下划线
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateGeneralWithChinese(T value, String errorMsg) throws ValidateException {
        if (!isGeneralWithChinese(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为 UUID<br>
     * 包括带横线标准格式和不带横线的简单模式
     *
     * @param value 值
     *
     * @return 是否为 UUID
     */
    public static boolean isUUID(CharSequence value) {
        return isMactchRegex(UUID, value) || isMactchRegex(UUID_SIMPLE, value);
    }

    /**
     * 验证是否为 UUID<br>
     * 包括带横线标准格式和不带横线的简单模式
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateUUID(T value, String errorMsg) throws ValidateException {
        if (!isUUID(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 验证是否为 Hex（16 进制）字符串
     *
     * @param value 值
     *
     * @return 是否为 Hex（16 进制）字符串
     */
    public static boolean isHex(CharSequence value) {
        return isMactchRegex(PatternPool.HEX, value);
    }

    /**
     * 验证是否为 Hex（16 进制）字符串
     *
     * @param <T> 字符串类型
     * @param value 值
     * @param errorMsg 验证错误的信息
     *
     * @return 验证后的值
     *
     * @throws ValidateException 验证异常
     */
    public static <T extends CharSequence> T validateHex(T value, String errorMsg) throws ValidateException {
        if (!isHex(value)) {
            throw new ValidateException(errorMsg);
        }
        return value;
    }

    /**
     * 检查给定的数字是否在指定范围内
     *
     * @param value 值
     * @param min 最小值（包含）
     * @param max 最大值（包含）
     *
     * @return 是否满足
     */
    public static boolean isBetween(Number value, Number min, Number max) {
        Assert.notNull(value);
        Assert.notNull(min);
        Assert.notNull(max);
        final double doubleValue = value.doubleValue();
        return (doubleValue >= min.doubleValue()) && (doubleValue <= max.doubleValue());
    }

    /**
     * 检查给定的数字是否在指定范围内
     *
     * @param value 值
     * @param min 最小值（包含）
     * @param max 最大值（包含）
     * @param errorMsg 验证错误的信息
     *
     * @throws ValidateException 验证异常
     */
    public static void validateBetween(Number value, Number min, Number max, String errorMsg) throws ValidateException {
        if (!isBetween(value, min, max)) {
            throw new ValidateException(errorMsg);
        }
    }

}
